import logging

from formencode import validators
from decorator import decorator
from bumblebee.lib.base import *
from bumblebee.lib.auth import redirect_to_login

log = logging.getLogger(__name__)

@decorator
def project_editable(func, *args, **kw):
    if c.project_editable:
        return func(*args, **kw)
    else:
        redirect_to_login()

class ProjectController(SecureController):

    def __before__(self):
        SecureController.__before__(self)
        project_id = session.get('current_project_id')
        if project_id:
            c.project = model.Project.get(project_id)
            #c.current_project = get_object_or_404(model.Project, id=project_id)
            if c.project.contact == c.current_user or h.in_group('admins'):
                c.project_editable = True
            else:
                c.project_editable = False
        c.show_all_notes = session.get('show_all_notes', False)
        c.show_closed_risks = session.get('show_closed_risks', False)
        c.show_closed_issues = session.get('show_closed_issues', False)


    def index(self):
        if c.project:
            return self.project()
        return self.locate()

    def locate(self):
        c.projects = model.Project.select_by(parent_project_id=None, archived=False)
        return render('/project/locate.mako')

    def select(self):
        session['current_project_id'] = request.params['project_id']
        session.save()
        redirect_to(action='project')

    def project(self):
        c.users = model.User.select()
        c.status_codes = [(v, k) for k, v in model.status_codes.iteritems()]
        return render('/project/project.mako')

    def toggle_show_all_notes(self):
        session['show_all_notes'] = not c.show_all_notes
        session.save()
        redirect_to(action='project')

    def toggle_closed_issues(self):
        session['show_closed_issues'] = not c.show_closed_issues
        session.save()
        redirect_to(action='project')

    @project_editable
    def toggle_archive_project(self):
        c.project.archived = not c.project.archived
        c.project.flush()
        redirect_to(action='project')

    def create_note(self):
        new_note = model.Note(note=request.params['note'], creator=c.current_user, project=c.project)
        new_note.flush()
        return render('/project/note.mako', note=new_note, read_only=False)
            
"""
		import turbogears           as tg
		import cherrypy
		import commands
		import socket
		import md5
		import time
		import random
		import os

		from turbogears             import identity, flash, validators
		from datetime               import datetime
		from whatwhat               import utils
		from textile                import textile
		from whatwhat.widgets       import widgets

		from whatwhat.model         import (Person, Project, Risk, Note, Question, 
		                                    Answer, Issue, chance_codes, impact_codes,
		                                    status_codes, ProjectFile)


		class ProjectController(identity.SecureResource):
		    require = identity.not_anonymous()

		    @tg.expose()
		    def default(self, *args, **kwargs):
		        parts = cherrypy.request.path.rsplit('/')
		        if len(parts) == 3 and parts[-1].isdigit():
		            return self.project(parts[-1])


		    @tg.expose()
		    def index(self, *args, **kwargs):        
		        project_id = self._active_project_id()
		        if project_id:
		            raise tg.redirect('/project/%s' % project_id)
		        return self.locate()


		    @tg.expose(template="whatwhat.templates.project.locate")
		    def locate(self):
		        all_projects = Project.select("parent_project_id is NULL order by upper(name)")
		        projects = [project for project in all_projects if not project.archived]

		        return dict(active_section='project',
		                    projects=projects)


		    @tg.expose(template="whatwhat.templates.project.project")
		    @tg.validate(validators=dict(project_id=validators.Int()))
		    def project(self, project_id):
		        project = Project.get(project_id)
		        user_person = Person.get(identity.current.user.id)
		        groupids = utils.getGroups()

		        cherrypy.response.simpleCookie['active_project_id'] = project_id
		        cherrypy.response.simpleCookie['active_project_id']['path'] = '/'

		        people = Person.select(orderBy='displayName')

		        return dict(active_section='project',
		                    project=project,
		                    chance_codes=chance_codes, 
		                    impact_codes=impact_codes,
		                    status_codes=status_codes,
		                    show_closed_risks=bool(self._show_closed_risks()),
		                    show_closed_issues=bool(self._show_closed_issues()),
		                    show_all_notes=bool(self._show_all_notes()),
		                    people=people,
		                    user_person=user_person,
		                    groupids=groupids,
		                    risks_widget=widgets.risks_widget,
		                    issues_widget=widgets.issues_widget,
		                    questions_widget=widgets.questions_widget,
		                    notes_widget=widgets.notes_widget)


		    @tg.expose()
		    def toggle_closed_risks(self):
		        if self._show_closed_risks():
		            cherrypy.response.simpleCookie['show_closed_risks'] = 0
		        else:
		            cherrypy.response.simpleCookie['show_closed_risks'] = 1
		        cherrypy.response.simpleCookie['show_closed_risks']['path'] = '/'

		        raise tg.redirect('/project/%s' % self._active_project_id())


		    @tg.expose()
		    def toggle_closed_issues(self):
		        if self._show_closed_issues():
		            cherrypy.response.simpleCookie['show_closed_issues'] = 0
		        else:
		            cherrypy.response.simpleCookie['show_closed_issues'] = 1
		        cherrypy.response.simpleCookie['show_closed_issues']['path'] = '/'

		        raise tg.redirect('/project/%s' % self._active_project_id())


		    @tg.expose()
		    def toggle_show_all_notes(self):
		        if self._show_all_notes():
		            cherrypy.response.simpleCookie['show_all_notes'] = 0
		        else:
		            cherrypy.response.simpleCookie['show_all_notes'] = 1
		        cherrypy.response.simpleCookie['show_all_notes']['path'] = '/'

		        raise tg.redirect('/project/%s' % self._active_project_id())


		    @tg.expose(fragment=True)
		    @tg.validate(validators=dict(impact=validators.Int(), description=validators.String()))
		    def create_issue(self, impact, description):
		        creator = Person.get(identity.current.user.id)
		        project = Project.get(self._active_project_id())

		        issues = list(project.issues)

		        issue = Issue(creator=creator, 
		                      project=project, 
		                      impact=impact,
		                      issue=description)

		        issues.append(issue)

		        return widgets.issues_widget.render(issues=issues)


		    @tg.expose(fragment=True)
		    @tg.validate(validators=dict(impact=validators.Int(), chance=validators.Int(), description=validators.String()))
		    def create_risk(self, impact, chance, description):
		        creator = Person.get(identity.current.user.id)
		        project = Project.get(self._active_project_id())

		        risks = list(project.risks)

		        risk = Risk(creator=creator, 
		                    project=project, 
		                    impact=impact, 
		                    chance=chance, 
		                    description=description)

		        risks.append(risk)

		        return widgets.risks_widget.render(risks=risks)


		    @tg.expose(fragment=True)
		    @tg.validate(validators=dict(question=validators.String()))
		    def create_question(self, question):
		        creator = Person.get(identity.current.user.id)
		        project = Project.get(self._active_project_id())

		        new_question = Question(creator=creator,
		                                project=project,
		                                question=question)

		        return widgets.question_widget.render(question=new_question)


		    @tg.expose(fragment=True)
		    @tg.validate(validators=dict(question_id=validators.Int(), answer=validators.String()))
		    def create_answer(self, question_id, answer):
		        creator = Person.get(identity.current.user.id)
		        question = Question.get(question_id)

		        new_answer = Answer(creator=creator,
		                            question=question,
		                            answer=answer)

		        return widgets.answer_widget.render(answer=new_answer)


		    @tg.expose(fragment=True)
		    @tg.validate(validators=dict(note=validators.String()))
		    def create_note(self, note):
		        creator = Person.get(identity.current.user.id)
		        project = Project.get(self._active_project_id())

		        note = Note(creator=creator, project=project, note=note)

		        return widgets.note_widget.render(note=note, read_only=False)


		    @tg.validate(validators=dict(note_id=validators.Int(), note=validators.String()))
		    @tg.expose(fragment=True)
		    def edit_note(self, note_id, note):
		        n = Note.get(note_id)
		        n.set(note=note, last_edit_date=datetime.now())

		        return widgets.note_widget.render(note=n)


		    @tg.expose()
		    @tg.validate(validators=dict(note_id=validators.Int()))
		    def remove_note(self, note_id):
		        note = Note.get(note_id)
		        Note.delete(note_id)
		        return dict(success=True)


		    @tg.expose(allow_json=True)
		    @tg.validate(validators=dict(note_id=validators.Int()))
		    def get_note_content(self, note_id, **kwargs):
		        note = Note.get(note_id)
		        cherrypy.response.headerMap['Pragma'] = 'no-cache'
		        cherrypy.response.headerMap['Cache-Control'] ='no-cache'
		        cherrypy.response.headerMap['Expires'] = -1

		        return dict(note=note.note)


		    @tg.expose(allow_json=True)
		    @tg.validate(validators=dict(risk_id=validators.Int()))
		    def close_risk(self, risk_id):
		        risk = Risk.get(risk_id)
		        risk.closed = True
		        return dict(success=True)


		    @tg.expose(allow_json=True)
		    @tg.validate(validators=dict(issue_id=validators.Int()))
		    def close_issue(self, issue_id):
		        issue = Issue.get(issue_id)
		        issue.closed = True
		        return dict(success=True)


		    @tg.expose(allow_json=True)
		    @tg.validate(validators=dict(risk_id=validators.Int(), impact=validators.Int(), chance=validators.Int()))
		    def modify_risk(self, risk_id, impact, chance):
		        risk = Risk.get(risk_id)
		        risk.set(impact=impact, chance=chance)
		        return dict(success=True)


		    @tg.expose(allow_json=True)
		    @tg.validate(validators=dict(question_id=validators.Int()))
		    def remove_question(self, question_id):
		        question = Question.get(question_id)

		        for answer in question.answers:
		            answer.destroySelf()

		        question.destroySelf()

		        return dict(success=True)


		    @tg.expose(allow_json=True)
		    @tg.validate(validators=dict(answer_id=validators.Int()))
		    def remove_answer(self, answer_id):
		        answer = Answer.get(answer_id)
		        answer.destroySelf()

		        return dict(success=True)


		    @tg.expose()
		    def new_file(self, file):
		        uploaddir = cherrypy.config.get('whatwhat.uploaddir')        
		        try:
		            if os.name == 'nt':
		                filename = file.filename
		                systemfilename = filename.split('.')[0] + self._uuid() + '.' + filename.split('.')[1]

		            else:
		                filename = file.filename
		                systemfilename = filename.split('.')[0] + self._uuidgen() + '.' + filename.split('.')[1]
		            f = open('%s%s' % (uploaddir, systemfilename), 'wb')
		            while 1:
		                data = file.file.read(1024*8)
		                if not data:break
		                f.write(data)
		            f.close()

		            creator = Person.get(cherrypy.request.identity.user.id)
		            project = Project.get(self._active_project_id())

		            ProjectFile(filename=filename, project=project, creator=creator, systemfilename=systemfilename)
		        except:
		            flash("Error creating file!")

		        raise tg.redirect('/project/%s' % project.id)


		    @tg.expose()
		    @tg.validate(validators=dict(file_id=validators.Int()))
		    def remove_file(self, file_id):
		        uploaddir = cherrypy.config.get('whatwhat.uploaddir')
		        file = ProjectFile.get(file_id)
		        os.unlink('%s%s' % (uploaddir, file.systemfilename))
		        ProjectFile.delete(file_id)

		        raise tg.redirect('/project/%s' % file.project.id)


		    @tg.expose(allow_json=True)    
		    @tg.validate(validators=dict(contact_id=validators.Int(), status=validators.Int(), description=validators.String()))
		    def update_project(self, contact_id, status, description):
		        contact = Person.get(contact_id)
		        project = Project.get(self._active_project_id())
		        project.set(status=int(status), contact=contact, description=description)
		        contact_content = '<a href="mailto:%s">%s</a>' % (contact.emailAddress, contact.displayName)
		        desc = textile(description.encode('utf-8'), encoding='utf-8', output='ascii')
		        return dict(success=True, description=desc, contact=contact_content)


		    @tg.expose(allow_json=True)
		    @tg.validate(validators=dict(issue_id=validators.Int(), impact=validators.Int()))
		    def modify_issue(self, issue_id, impact):
		        issue = Issue.get(issue_id)
		        issue.impact = impact
		        return dict(success=True)


		    @tg.expose()
		    def archive_project(self):
		        project = Project.get(self._active_project_id())
		        project.archived = True

		        raise tg.redirect('/project/%s' % project.id)


		    @tg.expose()
		    def unarchive_project(self):
		        project = Project.get(self._active_project_id())
		        project.archived = False

		        raise tg.redirect('/project/%s' % project.id)


		    def _uuidgen(self):
		        return commands.getoutput('uuidgen')


		    def _uuid(self):
		        t = long(time.time() * 1000)
		        r = long(random.random() * 100000000000000000L)
		        try:
		            a = socket.gethostbyname(socket.gethostname())
		        except:
		            # if we can't get a network address, just imagine one
		            a = random.random() * 100000000000000000L
		        data = str(t)+' '+str(r)+' '+str(a)
		        data = md5.md5(data).hexdigest()
		        return data

		    def _active_project_id(self):
		        if cherrypy.request.simpleCookie.has_key('active_project_id'):
		            return int(cherrypy.request.simpleCookie['active_project_id'].value)
		        return None

		    def _show_closed_issues(self):
		        if cherrypy.request.simpleCookie.has_key('show_closed_issues'):
		            return int(cherrypy.request.simpleCookie['show_closed_issues'].value)
		        return 0

		    def _show_closed_risks(self):
		        if cherrypy.request.simpleCookie.has_key('show_closed_risks'):
		            return int(cherrypy.request.simpleCookie['show_closed_risks'].value)
		        return 0

		    def _show_all_notes(self):
		        if cherrypy.request.simpleCookie.has_key('show_all_notes'):
		            return int(cherrypy.request.simpleCookie['show_all_notes'].value)
		        return 0
"""